Yalqov va faol yuklanish o'rtasidagi muhim farqlarni tushunib, SQLAlchemy unumdorligini oshiring. Qo'llanmada N+1 muammosini hal qilish uchun select, selectin, joined va subquery strategiyalari amaliy misollar bilan yoritilgan.
SQLAlchemy ORM munosabatlarini xaritalash: "Yalqov" va "Faol" yuklanishlarga chuqur nazar
Dasturiy ta'minotni ishlab chiqish dunyosida biz yozadigan obyektga yo'naltirilgan kod va ma'lumotlarimizni saqlaydigan relyatsion ma'lumotlar bazalari o'rtasidagi ko'prik unumdorlikning muhim chorrahasidir. Python dasturchilari uchun SQLAlchemy kuchli va moslashuvchan Obyekt-Relyatsion Xaritalash (ORM) vositasini taqdim etuvchi gigant sifatida maydonga chiqadi. U bizga ma'lumotlar bazasi jadvallari bilan go'yo ular oddiy Python obyektlari kabi ishlash imkonini beradi va xom SQLning katta qismini abstraktlashtiradi.
Ammo bu qulaylik jiddiy savolni keltirib chiqaradi: siz obyektning bog'liq ma'lumotlariga — masalan, muallif tomonidan yozilgan kitoblar yoki mijoz tomonidan berilgan buyurtmalarga — murojaat qilganingizda, bu ma'lumotlar ma'lumotlar bazasidan qanday va qachon olinadi? Javob SQLAlchemy'ning munosabatlarni yuklash strategiyalarida yotadi. Ular orasidagi tanlov chaqmoqdek tez ishlaydigan dastur bilan yuklama ostida to'xtab qoladigan dastur o'rtasidagi farqni anglatishi mumkin.
Ushbu keng qamrovli qo'llanma ma'lumotlarni yuklashning ikkita asosiy falsafasini: Yalqov yuklanish (Lazy Loading) va Faol yuklanish (Eager Loading)ni tushuntirib beradi. Biz yalqov yuklanish sabab bo'lishi mumkin bo'lgan mashhur "N+1 muammosi"ni o'rganamiz va SQLAlchemy uni hal qilish uchun taqdim etadigan turli xil faol yuklanish strategiyalari — joinedload, selectinload va subqueryloadga chuqur sho'ng'iymiz. Oxirida siz ongli qarorlar qabul qilish va global auditoriya uchun yuqori unumdorlikka ega ma'lumotlar bazasi kodini yozish uchun kerakli bilimlarga ega bo'lasiz.
Standart xatti-harakat: Yalqov yuklanishni tushunish
Odatiy bo'lib, siz SQLAlchemy'da munosabatni belgilaganingizda, u "yalqov yuklanish" deb nomlangan strategiyadan foydalanadi. Nomi o'zi juda tushunarli: ORM "yalqov" va siz aniq so'ramaguningizcha hech qanday bog'liq ma'lumotlarni olmaydi.
Yalqov yuklanish nima?
Yalqov yuklanish, xususan select strategiyasi, bog'liq obyektlarni yuklashni kechiktiradi. Siz birinchi marta ota-obyektni (masalan, Author) so'raganingizda, SQLAlchemy faqat shu muallif uchun ma'lumotlarni oladi. Bog'liq to'plam (masalan, muallifning books) tegmasdan qoladi. Faqatgina kodingiz birinchi marta author.books atributiga kirishga harakat qilganida SQLAlchemy uyg'onadi, ma'lumotlar bazasiga ulanadi va bog'liq kitoblarni olish uchun yangi SQL so'rovini yuboradi.
Buni ko'p jildli ensiklopediyaga buyurtma berishga o'xshatish mumkin. Yalqov yuklanish bilan siz dastlab birinchi jildni olasiz. Ikkinchi jildni faqat uni ochishga harakat qilganingizda so'raysiz va olasiz.
Yashirin xavf: "N+1 Selects" muammosi
Yalqov yuklanish, agar siz bog'liq ma'lumotlarga kamdan-kam ehtiyoj sezsangiz, samarali bo'lishi mumkin, ammo u N+1 Selects Muammosi deb nomlanuvchi mashhur unumdorlik tuzog'ini o'z ichiga oladi. Bu muammo siz ota-obyektlar to'plami bo'ylab iteratsiya qilganingizda va har biri uchun yalqov yuklanadigan atributga murojaat qilganingizda yuzaga keladi.
Keling, buni klassik misol bilan ko'rib chiqaylik: barcha mualliflarni olish va ularning kitoblarining sarlavhalarini chop etish.
- Siz N ta muallifni olish uchun bitta so'rov yuborasiz. (1 ta so'rov)
- Keyin siz Python kodingizda ushbu N ta muallif bo'ylab sikl orqali o'tasiz.
- Sikl ichida, birinchi muallif uchun siz
author.booksga murojaat qilasiz. SQLAlchemy o'sha muallifning kitoblarini olish uchun yangi so'rov yuboradi. - Ikkinchi muallif uchun siz yana
author.booksga murojaat qilasiz. SQLAlchemy ikkinchi muallifning kitoblari uchun yana bir so'rov yuboradi. - Bu barcha N ta muallif uchun davom etadi. (N ta so'rov)
Natija? Ma'lumotlar bazangizga jami 1 + N ta so'rov yuboriladi. Agar sizda 100 ta muallif bo'lsa, siz 101 marta alohida ma'lumotlar bazasiga murojaat qilasiz! Bu sezilarli kechikishni keltirib chiqaradi va ma'lumotlar bazangizga keraksiz yuklama tushiradi, bu esa dastur unumdorligini jiddiy pasaytiradi.
Yalqov yuklanishning amaliy misoli
Keling, buni kodda ko'rib chiqaylik. Avval modellarimizni aniqlaymiz:
from sqlalchemy import create_engine, Column, Integer, String, ForeignKey
from sqlalchemy.orm import sessionmaker, declarative_base, relationship
Base = declarative_base()
class Author(Base):
__tablename__ = 'authors'
id = Column(Integer, primary_key=True)
name = Column(String)
# Bu munosabat sukut bo'yicha lazy='select' ga o'rnatilgan
books = relationship("Book", back_populates="author")
class Book(Base):
__tablename__ = 'books'
id = Column(Integer, primary_key=True)
title = Column(String)
author_id = Column(Integer, ForeignKey('authors.id'))
author = relationship("Author", back_populates="books")
# Dvigatel va sessiyani sozlash (generatsiya qilingan SQLni ko'rish uchun echo=True dan foydalaning)
engine = create_engine('sqlite:///:memory:', echo=True)
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
# ... (mualliflar va kitoblar qo'shish kodi)
Endi N+1 muammosini keltirib chiqaramiz:
# 1. Barcha mualliflarni olish (1 ta so'rov)
print("--- Mualliflarni olish ---")
authors = session.query(Author).all()
# 2. Har bir muallif uchun kitoblarga murojaat qilish va sikl orqali o'tish (N ta so'rov)
print("--- Har bir muallif kitoblariga murojaat qilish ---")
for author in authors:
# Bu qator har bir muallif uchun yangi SELECT so'rovini ishga tushiradi!
book_titles = [book.title for book in author.books]
print(f"{author.name}ning kitoblari: {book_titles}")
Agar siz ushbu kodni echo=True bilan ishga tushirsangiz, loglaringizda quyidagi naqshni ko'rasiz:
--- Mualliflarni olish ---
SELECT authors.id AS authors_id, authors.name AS authors_name FROM authors
--- Har bir muallif kitoblariga murojaat qilish ---
SELECT books.id AS books_id, ... FROM books WHERE ? = books.author_id
SELECT books.id AS books_id, ... FROM books WHERE ? = books.author_id
SELECT books.id AS books_id, ... FROM books WHERE ? = books.author_id
...
Yalqov yuklanish qachon yaxshi g'oya?
N+1 tuzog'iga qaramay, yalqov yuklanish o'z-o'zidan yomon emas. To'g'ri qo'llanilganda u foydali vositadir:
- Ixtiyoriy ma'lumotlar: Bog'liq ma'lumotlar faqat maxsus, kam uchraydigan holatlarda kerak bo'lganda. Masalan, foydalanuvchi profilini yuklash, lekin uning batafsil faoliyat jurnalini faqat u maxsus "Tarixni ko'rish" tugmasini bosganda olish.
- Yagona obyekt konteksti: Siz to'plam bilan emas, balki bitta ota-obyekt bilan ishlayotganingizda. Bitta foydalanuvchini olib, keyin uning manzillariga (`user.addresses`) murojaat qilish faqat bitta qo'shimcha so'rovga olib keladi, bu ko'pincha mutlaqo qabul qilinadi.
Yechim: Faol yuklanishni qabul qilish
Faol yuklanish yalqov yuklanishga proaktiv alternativadir. U SQLAlchemy'ga bog'liq ma'lumotlarni ota-obyekt(lar) bilan bir vaqtda, samaraliroq so'rov strategiyasidan foydalanib olishni buyuradi. Uning asosiy maqsadi - so'rovlar sonini kichik, oldindan aytish mumkin bo'lgan songa (ko'pincha bir yoki ikkiga) kamaytirish orqali N+1 muammosini yo'q qilishdir.
SQLAlchemy so'rov opsiyalari yordamida sozlanadigan bir nechta kuchli faol yuklanish strategiyalarini taqdim etadi. Keling, eng muhimlarini ko'rib chiqaylik.
1-strategiya: joined yuklanish
Joined yuklanish, ehtimol, eng intuitiv faol yuklanish strategiyasidir. U SQLAlchemy'ga ota-obyektni va uning barcha bog'liq bola-obyektlarini bitta, katta ma'lumotlar bazasi so'rovida olish uchun SQL JOIN (xususan, LEFT OUTER JOIN) dan foydalanishni aytadi.
- Qanday ishlaydi: U ota va bola jadvallarining ustunlarini bitta keng natijalar to'plamiga birlashtiradi. So'ngra SQLAlchemy Pythonda ota-obyektlarni aqlli ravishda takrorlanishlardan tozalaydi va bola to'plamlarini to'ldiradi.
- Qanday foydalanish kerak:
joinedloadso'rov opsiyasidan foydalaning.
from sqlalchemy.orm import joinedload
# Barcha mualliflarni va ularning kitoblarini bitta so'rovda olish
authors = session.query(Author).options(joinedload(Author.books)).all()
for author in authors:
# Bu yerda yangi so'rov ishga tushirilmaydi!
book_titles = [book.title for book in author.books]
print(f"{author.name}ning kitoblari: {book_titles}")
Generatsiya qilingan SQL quyidagicha ko'rinishga ega bo'ladi:
SELECT authors.id, authors.name, books.id, books.title, books.author_id
FROM authors LEFT OUTER JOIN books ON authors.id = books.author_id
`joinedload`ning afzalliklari:
- Yagona ma'lumotlar bazasiga murojaat: Barcha kerakli ma'lumotlar bir martada olinadi, bu tarmoq kechikishini minimallashtiradi.
- Juda samarali: Ko'pdan-birga yoki birdan-birga munosabatlar uchun bu ko'pincha eng tezkor variantdir.
`joinedload`ning kamchiliklari:
- Dekart ko'paytmasi: Birdan-ko'pga munosabatlar uchun bu ortiqcha ma'lumotlarga olib kelishi mumkin. Agar muallifning 20 ta kitobi bo'lsa, muallifning ma'lumotlari (ismi, id'si va h.k.) ma'lumotlar bazasidan dasturingizga yuborilgan natijalar to'plamida 20 marta takrorlanadi. Bu xotira va tarmoqdan foydalanishni oshirishi mumkin.
- LIMIT/OFFSET bilan bog'liq muammolar: To'plamda `joinedload` bilan so'rovga `limit()` qo'llash kutilmagan natijalarga olib kelishi mumkin, chunki limit ota-obyektlar soniga emas, balki birlashtirilgan qatorlarning umumiy soniga qo'llaniladi.
2-strategiya: selectin yuklanish (Zamonaviy tanlov)
selectin yuklanish birdan-ko'pga to'plamlarni yuklash uchun zamonaviyroq va ko'pincha ustunroq strategiyadir. U so'rov soddaligi va unumdorlik o'rtasida ajoyib muvozanatni saqlaydi va `joinedload`ning asosiy kamchiliklaridan qochadi.
- Qanday ishlaydi: U yuklashni ikki bosqichda amalga oshiradi:
- Birinchidan, u ota-obyektlar uchun so'rovni bajaradi (masalan, `authors`).
- Keyin, u barcha yuklangan ota-obyektlarning birlamchi kalitlarini to'playdi va yuqori samarali `WHERE ... IN (...)` bandidan foydalanib, barcha bog'liq bola-obyektlarni (masalan, `books`) olish uchun ikkinchi so'rovni yuboradi.
- Qanday foydalanish kerak:
selectinloadso'rov opsiyasidan foydalaning.
from sqlalchemy.orm import selectinload
# Mualliflarni olish, so'ngra ularning barcha kitoblarini ikkinchi so'rovda olish
authors = session.query(Author).options(selectinload(Author.books)).all()
for author in authors:
# Hali ham har bir muallif uchun yangi so'rov yo'q!
book_titles = [book.title for book in author.books]
print(f"{author.name}ning kitoblari: {book_titles}")
Bu ikkita alohida, toza SQL so'rovini generatsiya qiladi:
-- 1-so'rov: Ota-obyektlarni olish
SELECT authors.id AS authors_id, authors.name AS authors_name FROM authors
-- 2-so'rov: Barcha bog'liq bo'lgan bola obyektlarni bir vaqtda olish
SELECT books.id AS books_id, ... FROM books WHERE books.author_id IN (?, ?, ?, ...)
`selectinload`ning afzalliklari:
- Ortiqcha ma'lumotlar yo'q: U Dekart ko'paytmasi muammosini butunlay chetlab o'tadi. Ota va bola ma'lumotlari toza uzatiladi.
- LIMIT/OFFSET bilan ishlaydi: Ota-so'rov alohida bo'lgani uchun siz `limit()` va `offset()` ni hech qanday muammosiz ishlatishingiz mumkin.
- Soddaroq SQL: Generatsiya qilingan so'rovlarni ma'lumotlar bazasi uchun optimallashtirish ko'pincha osonroq bo'ladi.
- Eng yaxshi umumiy maqsadli tanlov: Aksariyat ko'pga-munosabatlar uchun bu tavsiya etilgan strategiyadir.
`selectinload`ning kamchiliklari:
- Bir nechta ma'lumotlar bazasiga murojaat: U har doim kamida ikkita so'rovni talab qiladi. Samarali bo'lsa-da, bu texnik jihatdan `joinedload`ga qaraganda ko'proq murojaatdir.
- `IN` bandining cheklovlari: Ba'zi ma'lumotlar bazalarida `IN` bandidagi parametrlar soni bo'yicha cheklovlar mavjud. SQLAlchemy buni zarur bo'lganda operatsiyani bir nechta so'rovlarga bo'lish orqali hal qilish uchun yetarlicha aqlli, ammo bu e'tiborga olish kerak bo'lgan omil.
3-strategiya: subquery yuklanish
subquery yuklanish - bu `lazy` va `joined` yuklanishning gibridi sifatida ishlaydigan ixtisoslashtirilgan strategiyadir. U `joinedload`ni `limit()` yoki `offset()` bilan ishlatishning maxsus muammosini hal qilish uchun mo'ljallangan.
- Qanday ishlaydi: U ham barcha ma'lumotlarni bitta so'rovda olish uchun `JOIN`dan foydalanadi. Biroq, u avval ota-obyektlar uchun so'rovni (shu jumladan `LIMIT`/`OFFSET`ni) ichki so'rov (subquery) ichida bajaradi, so'ngra bog'liq jadvalni o'sha ichki so'rov natijasiga birlashtiradi.
- Qanday foydalanish kerak:
subqueryloadso'rov opsiyasidan foydalaning.
from sqlalchemy.orm import subqueryload
# Dastlabki 5 ta muallifni va ularning barcha kitoblarini olish
authors = session.query(Author).options(subqueryload(Author.books)).limit(5).all()
Generatsiya qilingan SQL murakkabroq:
SELECT ...
FROM (SELECT authors.id AS authors_id, authors.name AS authors_name
FROM authors LIMIT 5) AS anon_1
LEFT OUTER JOIN books ON anon_1.authors_id = books.author_id
`subqueryload`ning afzalliklari:
- LIMIT/OFFSET bilan JOIN qilishning to'g'ri usuli: U limitni birlashtirishdan oldin ota-obyektlarga to'g'ri qo'llaydi, bu sizga kutilgan natijalarni beradi.
- Yagona ma'lumotlar bazasiga murojaat: `joinedload` kabi, u barcha ma'lumotlarni bir martada oladi.
`subqueryload`ning kamchiliklari:
- SQL murakkabligi: Generatsiya qilingan SQL murakkab bo'lishi mumkin va uning unumdorligi turli ma'lumotlar bazasi tizimlarida farq qilishi mumkin.
- Hali ham Dekart ko'paytmasi mavjud: U hali ham `joinedload` bilan bir xil ortiqcha ma'lumotlar muammosiga duch keladi.
Taqqoslash jadvali: O'z strategiyangizni tanlash
Qaysi yuklash strategiyasini qo'llashni hal qilishda sizga yordam beradigan tezkor ma'lumotnoma jadvali.
| Strategiya | Qanday ishlaydi | So'rovlar soni | Eng yaxshi holatlar | Ehtiyot choralari |
|---|---|---|---|---|
lazy='select' (Standart) |
Atributga birinchi marta murojaat qilinganda yangi SELECT so'rovini yuboradi. | 1 + N | Yagona obyekt uchun bog'liq ma'lumotlarga kirish; bog'liq ma'lumotlar kamdan-kam kerak bo'lganda. | Sikllarda N+1 muammosi yuzaga kelish xavfi yuqori. |
joinedload |
Ota va bola ma'lumotlarini birga olish uchun bitta LEFT OUTER JOIN ishlatadi. | 1 | Ko'pdan-birga yoki birdan-birga munosabatlar. Yagona so'rov juda muhim bo'lganda. | Ko'pga-munosabatli to'plamlar bilan Dekart ko'paytmasini keltirib chiqaradi; `limit()`/`offset()` ni buzadi. |
selectinload |
Barcha ota-IDlar uchun `IN` bandi bilan ikkinchi SELECT so'rovini yuboradi. | 2+ | Birdan-ko'pga to'plamlar uchun eng yaxshi standart tanlov. `limit()`/`offset()` bilan mukammal ishlaydi. | Birdan ortiq ma'lumotlar bazasiga murojaat qilishni talab qiladi. |
subqueryload |
Ota-so'rovni ichki so'rovga o'raydi, so'ng bola-jadvalni birlashtiradi. | 1 | JOIN orqali to'plamni faol yuklashi kerak bo'lgan so'rovga `limit()` yoki `offset()` ni qo'llash. | Murakkab SQL generatsiya qiladi; hali ham Dekart ko'paytmasi muammosi mavjud. |
Ilg'or yuklanish usullari
Asosiy strategiyalardan tashqari, SQLAlchemy munosabatlarni yuklash ustidan yanada nozik nazoratni taklif qiladi.
raiseload yordamida tasodifiy yalqov yuklanishlarning oldini olish
SQLAlchemy'dagi eng yaxshi himoyaviy dasturlash naqshlaridan biri bu raiseloaddan foydalanishdir. Bu strategiya yalqov yuklanishni istisno bilan almashtiradi. Agar kodingiz so'rovda aniq faol yuklanmagan munosabatga kirishga harakat qilsa, SQLAlchemy InvalidRequestError xatosini chiqaradi.
from sqlalchemy.orm import raiseload
# Muallif uchun so'rov, lekin uning kitoblarini yalqov yuklashni aniq taqiqlash
author = session.query(Author).options(raiseload(Author.books)).first()
# Bu qator endi istisno chiqaradi va yashirin N+1 so'rovining oldini oladi!
print(author.books)
Bu ishlab chiqish va testlash jarayonida juda foydali. Muhim munosabatlarga standart sifatida raiseload o'rnatib, siz dasturchilarni o'zlarining ma'lumotlarni yuklash ehtiyojlari haqida ongli bo'lishga majbur qilasiz, bu esa N+1 muammolarining productionga o'tib ketish ehtimolini samarali ravishda yo'q qiladi.
noload bilan munosabatni e'tiborsiz qoldirish
Ba'zan siz munosabatning hech qachon yuklanmasligini ta'minlashni xohlaysiz. noload opsiyasi SQLAlchemy'ga atributni bo'sh qoldirishni (masalan, bo'sh ro'yxat yoki None) aytadi. Bu ma'lumotlarni seriyalashda (masalan, JSONga o'tkazishda) foydalidir, bunda siz hech qanday ma'lumotlar bazasi so'rovlarini ishga tushirmasdan, ma'lum maydonlarni natijadan chiqarib tashlamoqchi bo'lasiz.
Dinamik yuklanish bilan katta hajmdagi to'plamlarni boshqarish
Agar muallif minglab kitoblar yozgan bo'lsa-chi? Ularning barchasini `selectinload` bilan xotiraga yuklash samarasiz bo'lishi mumkin. Bunday holatlar uchun SQLAlchemy to'g'ridan-to'g'ri munosabatda sozlanadigan dynamic yuklanish strategiyasini taqdim etadi.
class Author(Base):
# ...
# Juda katta kolleksiyalar uchun lazy='dynamic' dan foydalaning
books = relationship("Book", back_populates="author", lazy='dynamic')
Ro'yxat qaytarish o'rniga, `lazy='dynamic'` atributi so'rov obyektini qaytaradi. Bu sizga har qanday ma'lumot haqiqatda yuklanishidan oldin qo'shimcha filtrlash, tartiblash yoki sahifalashni zanjirband qilish imkonini beradi.
author = session.query(Author).first()
# author.books endi ro'yxat emas, balki so'rov obyekti
# Hali hech qanday kitob yuklanmagan!
# Kitoblarni yuklamasdan sanash
book_count = author.books.count()
# Sarlavha bo'yicha tartiblangan dastlabki 10 ta kitobni olish
first_ten_books = author.books.order_by(Book.title).limit(10).all()
Amaliy ko'rsatmalar va eng yaxshi amaliyotlar
- Taxmin qilmang, profillang: Unumdorlikni optimallashtirishning oltin qoidasi - o'lchashdir. Generatsiya qilinayotgan aniq SQL so'rovlarini tekshirish uchun SQLAlchemy'ning `echo=True` dvigatel flagidan yoki SQLAlchemy-Debugbar kabi murakkabroq vositadan foydalaning. Muammolarni tuzatishga urinishdan oldin ularni aniqlang.
- Himoyaviy standart o'rnating, aniq bekor qiling: Ajoyib naqsh - bu modelingizda
lazy='raiseload'kabi himoyaviy standartni o'rnatish. Bu har bir so'rovni o'ziga nima kerakligi haqida aniq bo'lishga majbur qiladi. Keyin, har bir maxsus repozitoriy funksiyasi yoki xizmat qatlami usulida, o'sha holat uchun talab qilinadigan aniq yuklash strategiyasini (`selectinload`, `joinedload` va h.k.) belgilash uchunquery.options()dan foydalaning. - Yuklanishlaringizni zanjirband qiling: Ichki munosabatlar uchun (masalan, Muallif, uning Kitoblari va har bir Kitobning Sharhlarini yuklash), siz yuklovchi opsiyalaringizni zanjirband qilishingiz mumkin:
options(selectinload(Author.books).selectinload(Book.reviews)). - Ma'lumotlaringizni biling: To'g'ri tanlov har doim ma'lumotlaringiz shakliga va dasturingizning murojaat naqshlariga bog'liq. Bu birdan-birga yoki birdan-ko'pga munosabatmi? To'plamlar odatda kichikmi yoki kattami? Sizga har doim ma'lumotlar kerak bo'ladimi yoki faqat ba'zida? Ushbu savollarga javob berish sizni optimal strategiyaga yo'naltiradi.
Xulosa: Yangi boshlovchidan unumdorlik mutaxassisigacha
SQLAlchemy'ning munosabatlarni yuklash strategiyalarini boshqarish - bu mustahkam, kengaytiriladigan dasturlarni yaratuvchi har qanday dasturchi uchun asosiy mahoratdir. Biz standart `lazy='select'` va uning yashirin N+1 unumdorlik tuzog'idan `selectinload` va `joinedload` kabi faol yuklanish strategiyalari taklif qiladigan kuchli, aniq nazoratga qadar sayohat qildik.
Asosiy xulosa shuki: ongli bo'ling. Unumdorlik muhim bo'lganda standart xatti-harakatlarga tayanmang. Ma'lum bir vazifa uchun dasturingizga qanday ma'lumotlar kerakligini tushuning va so'rovlaringizni aynan shu ma'lumotlarni eng samarali usulda olish uchun yozing. Ushbu yuklash strategiyalarini o'zlashtirish orqali siz shunchaki ORMni ishlatishdan tashqariga chiqasiz; siz uni o'zingiz uchun ishlashga majbur qilasiz, nafaqat funksional, balki ajoyib darajada tez va samarali dasturlarni yaratasiz.